package com.homer.gps.track;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnShowListener;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.Window;
import com.homer.gps.track.helper.DirectoryHelper;
import com.homer.gps.track.helper.ImageCaptHelper;
import com.homer.gps.track.helper.ImageHelper;
import com.homer.gps.track.helper.UsefullStaff;
import com.homer.gps.track.helper.UsefullStaff.Dir;
import com.homer.gps.track.persist.DatabaseHelper;
import com.homer.gps.track.persist.PlaceModel;
import com.homer.gps.track.persist.Repository;
import com.homer.gps.track.persist.RouteModel;
import com.j256.ormlite.android.apptools.OpenHelperManager;

public class PlaceEdit extends SherlockActivity{
	
	public static final int REQUEST_CODE_CAMERA = 0;
	public static final int REQUEST_CODE_GALLERY = 1;

	private TextView name, street, house_number, postal_code, city, type, note, placeType;
	private int selected_id;
	private PlaceModel selected_place = null;
	private LocationManager locationManager;
	private LocationListener locationListener;
	private ImageCaptHelper imageHelper;
	private String photoPath;
	private String newPhotoPath;
	private ImageView photo;

	private Repository repository;
	private DatabaseHelper dbHelper = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		setContentView(R.layout.place_edit);
		setSupportProgressBarIndeterminateVisibility(false);

		selected_id = getIntent().getIntExtra("id", -1);
		this.repository = new Repository(getHelper());
		initActivity();

		locationListener = new LocationListener() {
			private Location currentBestLocation;

			public void onLocationChanged(Location location) {
				if (isBetterLocation(location, currentBestLocation))
					currentBestLocation = location;
				float accuracy = currentBestLocation.getAccuracy();
				if (accuracy > 0.0f && accuracy < 50.0f) {

					locationManager.removeUpdates(this);
					double latitude = currentBestLocation.getLatitude();
					double longitude = currentBestLocation.getLongitude();

					AsyncTask<Double, Void, Address> aTask = new AsyncTask<Double, Void, Address>() {

						@Override
						protected Address doInBackground(Double... params) {
							try {
								//Geocoder coder = new Geocoder(PlaceEdit.this, LocaleDelegate.getPreferenceLocale(PlaceEdit.this));
								Geocoder coder = new Geocoder(PlaceEdit.this);
								return coder.getFromLocation(params[0], params[1], 1).get(0);
							} catch (IOException e) {
								e.printStackTrace();
								return null;
							}
						}

						@Override
						protected void onPostExecute(Address result) {
							if (result != null)
								fillForm(result);
							setSupportProgressBarIndeterminateVisibility(false);
						}
					};
					aTask.execute(new Double[]{latitude, longitude});
				}
			}

			public void onStatusChanged(String provider, int status, Bundle extras) {
				Log.d(getPackageName(), "onStatusChanged " + status);
			}

			public void onProviderEnabled(String provider) {
				Log.d(getPackageName(), "onProviderEnabled");
			}

			public void onProviderDisabled(String provider) {
				Log.d(getPackageName(), "onProviderDisabled");
			}
		};
	}

	private void initActivity() {
		getSupportActionBar().setTitle(R.string.title_place_edit);
		getSupportActionBar().setHomeButtonEnabled(true);
		name = (TextView) findViewById(R.id.place_name);
		street = (TextView) findViewById(R.id.street);
		house_number = (TextView) findViewById(R.id.house_no);
		postal_code = (TextView) findViewById(R.id.postal_code);
		city = (TextView) findViewById(R.id.city);
		type = (TextView) findViewById(R.id.place_type);
		note = (TextView) findViewById(R.id.place_note);
		photo = (ImageView) findViewById(R.id.picture_holder);
		placeType = (TextView) findViewById(R.id.place_type);
		
		if(selected_id != -1){
			selected_place = repository.getPlaceForId(selected_id);
			getSupportActionBar().setTitle(selected_place.getName().toString());
			name.setText(selected_place.getName().toString());
			String[] placeTypes = getResources().getStringArray(R.array.place_types);
			int placeTypePos = ((PlaceModel)repository.getPlaceForId(selected_place.getId())).getType();
			placeType.setText(placeTypes[placeTypePos]);
			street.setText(selected_place.getStreet().toString());
			house_number.setText(selected_place.getHouse_number().toString());
			postal_code.setText(selected_place.getPostal_code().toString());
			city.setText(selected_place.getCity().toString());
			note.setText(selected_place.getNote().toString());
			photoPath = selected_place.getImagePath();
			if (photoPath != null) {
				Bitmap decodedBitmap = ImageHelper.decodeBitmap(photoPath.toString());
				if (decodedBitmap != null){
					photo.setImageBitmap(decodedBitmap);
				}
			}
		}
	}

	protected void fillForm(Address address) {
		street.setText(address.getThoroughfare());
		house_number.setText(address.getFeatureName());
		postal_code.setText(address.getPostalCode());
		city.setText(address.getLocality());

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		menu.add("Text")
		.setIcon(R.drawable.btn_check_buttonless_on)
		.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);

		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle item selection
		switch (item.getItemId()) {
		case android.R.id.home:
			finish();
			return true;
		case 0:
			onSaveButtonClicked();
			return true;
		case 1:
			finish();
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	@Override
	public void onBackPressed() {
		setResult(RESULT_CANCELED);
		super.onBackPressed();
	}

	private void onSaveButtonClicked(){
		if (name.getText().length() <= 0) {
			Toast.makeText(this, R.string.required_value, Toast.LENGTH_SHORT).show();
			name.requestFocus();
			name.setError(getString(R.string.required_value));
			return;
		}
		if (type.getText().length() <= 0) {
			Toast.makeText(this, R.string.required_value, Toast.LENGTH_SHORT).show();
			type.requestFocus();
			type.setError(getString(R.string.required_value));
			return;
		}
		
		PlaceModel place = null;
		if (selected_place == null) {
			place = new PlaceModel();
		}else {
			place = selected_place;
		}
		
		place.setName(name.getText().toString());
		List<String> types = Arrays.asList(getResources().getStringArray(R.array.place_types));
		place.setType(types.indexOf(placeType.getText()));
		place.setStreet(street.getText().toString());
		place.setHouse_number(house_number.getText().toString());
		place.setPostal_code(postal_code.getText().toString());
		place.setCity(city.getText().toString());
		place.setNote(note.getText().toString());
		if (newPhotoPath != null){
			place.setImagePath(newPhotoPath);
		}
		repository.saveOrUpdatePlace(place);
		setResult(RESULT_OK);
		finish();
	}

	private DatabaseHelper getHelper() {
		if (dbHelper == null) {
			dbHelper = (DatabaseHelper)OpenHelperManager.getHelper(this, DatabaseHelper.class);
		}
		return dbHelper;
	}

	public void onGPSFindClicked (View view) {
		setSupportProgressBarIndeterminateVisibility(true);
		boolean enabled = false;

		locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
		if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
			locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
			enabled = true;
		}

		if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { 
			locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
			enabled = true;
		}

		if (!enabled) {
			//workingLayout.setVisibility(View.INVISIBLE);

			AlertDialog.Builder builder = new Builder(this);
			//builder.setTitle(getString(R.string.location_access_disabled));
			//builder.setMessage(getString(R.string.enable_location_question));
			builder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {

				@Override
				public void onClick(DialogInterface dialog, int which) {
					Intent intent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
					startActivity(intent);
				}
			});
			builder.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {

				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
				}

			});
			builder.create().show();
		}
	} 

	protected boolean isBetterLocation(Location location, Location currentBestLocation) {
		if (currentBestLocation == null) {
			return true;
		}

		// Check whether the new location fix is newer or older
		long timeDelta = location.getTime() - currentBestLocation.getTime();
		boolean isNewer = timeDelta > 0;

		// Check whether the new location fix is more or less accurate
		int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
		boolean isLessAccurate = accuracyDelta > 0;
		boolean isMoreAccurate = accuracyDelta < 0;
		boolean isSignificantlyLessAccurate = accuracyDelta > 200;

		// Check if the old and new location are from the same provider
		boolean isFromSameProvider = isSameProvider(location.getProvider(), currentBestLocation.getProvider());

		// Determine location quality using a combination of timeliness and accuracy
		if (isMoreAccurate) {
			return true;
		} else if (isNewer && !isLessAccurate) {
			return true;
		} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
			return true;
		}
		return false;
	}

	/** Checks whether two providers are the same */
	private boolean isSameProvider(String provider1, String provider2) {
		if (provider1 == null) {
			return provider2 == null;
		}
		return provider1.equals(provider2);
	}

	public void onPlaceValueClicked (View view) {
		View selectedView = view;
		TextView title = (TextView) view.findViewById(R.id.title);
		TextView value;
		switch (selectedView.getId()) {
		case R.id.name_layout:
			value = (TextView) view.findViewById(R.id.place_name);
			getInputDialog(view, title.getText(), value).show();
			break;
		case R.id.type_layout:
			value = (TextView) view.findViewById(R.id.place_type);
			getInputDialog(view, title.getText(), value).show();
			break;
		case R.id.street_layout:
			value = (TextView) view.findViewById(R.id.street);
			getInputDialog(view, title.getText(), value).show();
			break;
		case R.id.house_no_layout:
			value = (TextView) view.findViewById(R.id.house_no);
			getInputDialog(view, title.getText(), value).show();
			break;
		case R.id.postal_code_layout:
			value = (TextView) view.findViewById(R.id.postal_code);
			getInputDialog(view, title.getText(), value).show();
			break;
		case R.id.city_layout:
			value = (TextView) view.findViewById(R.id.city);
			getInputDialog(view, title.getText(), value).show();
			break;
		case R.id.note_layout:
			value = (TextView) view.findViewById(R.id.place_note);
			getInputDialog(view, title.getText(), value).show();
			break;
		default:
			break;
		}
	}
	
	public void onPictureClicked(View view) {
		//		((ScrollView)findViewById(R.id.scrollView)).smoothScrollTo(0, view.getBottom());
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle(R.string.select_action)
		.setItems(R.array.picture_actions, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				switch (which) {
				case 0:
					PackageManager pm = getPackageManager();
					if (pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
						imageHelper = new ImageCaptHelper(getApplicationContext(), PlaceEdit.this, UsefullStaff.getExternalStorageDir(getApplicationContext(), Dir.IMAGE, "") + File.separator + getString(R.string.places_images_folder), false);
						Intent takePicture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
						takePicture.putExtra(MediaStore.EXTRA_OUTPUT, imageHelper.getCurrentUri());
						startActivityForResult(takePicture, REQUEST_CODE_CAMERA);
					} else {
						Toast.makeText(getApplicationContext(), getString(R.string.camera_required), Toast.LENGTH_SHORT).show();
					}
					break;
				case 1:
					imageHelper = new ImageCaptHelper(getApplicationContext(), PlaceEdit.this,  UsefullStaff.getExternalStorageDir(getApplicationContext(), Dir.IMAGE, "") + File.separator + getString(R.string.places_images_folder), false);
					Intent pickPhoto = new Intent();
					pickPhoto.setAction(Intent.ACTION_PICK);
					pickPhoto.setData(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
					pickPhoto.setType("image/*");
					startActivityForResult(pickPhoto, REQUEST_CODE_GALLERY);
					break;
				case 2:
					//newPictureLayout.setVisibility(View.GONE);
					break;

				default:
					break;
				}
			}
		});
		builder.create().show();
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch (requestCode) {
		case REQUEST_CODE_GALLERY:
			if (resultCode == RESULT_OK) {
				sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
				String path = imageHelper.getImageFromGallery(data);
				ImageHelper.rotateImage(path);
				if (newPhotoPath != null)
					DirectoryHelper.deleteFile(newPhotoPath);
				newPhotoPath = path;
				photo.setImageBitmap(ImageHelper.decodeBitmap(path));
				//onCancelClicked(null);
			}
			break;
		case REQUEST_CODE_CAMERA:
			if (resultCode == RESULT_OK) {
				String path = imageHelper.getCurrentUri().getPath();
				ImageHelper.rotateImage(path);
				if (newPhotoPath != null)
					DirectoryHelper.deleteFile(newPhotoPath);
				newPhotoPath = path;
				photo.setImageBitmap(ImageHelper.decodeBitmap(path));
				//onCancelClicked(null);
			}
			break;
		default:
			super.onActivityResult(requestCode, resultCode, data);
			break;
		}
	}

	private AlertDialog getInputDialog(final View view, final CharSequence title, final TextView value) {
		AlertDialog.Builder alert = new AlertDialog.Builder(this);

		alert.setTitle(title);
		alert.setMessage(null);

		final EditText input = new EditText(this);
		final ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
				this, R.array.place_types, android.R.layout.simple_list_item_single_choice);
		if (value.getId() == R.id.place_type) {
			alert.setSingleChoiceItems(adapter, 1, new OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
				}
			});
		}else {
			if (value.getInputType() != 0)
				input.setInputType(value.getInputType());
			if (value.getText().length() > 0)
				input.setText(value.getText());
			alert.setView(input);
		}

		alert.setPositiveButton(getString(android.R.string.ok), new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				String text;
				if (value.getId() == R.id.place_type) {
					int selectedPosition = ((AlertDialog)dialog).getListView().getCheckedItemPosition();
					text = (String)adapter.getItem(selectedPosition);
				}else{
					text = input.getText().toString();
				}
				if (text.length() > 0) {
					value.setText(text);
				}
				else {
					value.setText("");
				}
			}
		});

		alert.setNegativeButton(getString(android.R.string.cancel), new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
			}
		});

		AlertDialog dialog = alert.create();
		dialog.setOnShowListener(new OnShowListener() {

			@Override
			public void onShow(DialogInterface dialog) {
				if (value.getId() != R.id.place_type) {
					InputMethodManager inputMethodManager=(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
					inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, InputMethodManager.HIDE_NOT_ALWAYS);
				}
			}
		});
		return dialog;
	}

	@Override
	protected void onDestroy() {

		if (locationManager != null)
			locationManager.removeUpdates(locationListener);
		super.onDestroy();
	}
}
